import React ,{
    Fragment,
    PureComponent
} from 'react';

import {
    View,
    Dimensions,
    ViewStyle,
    StyleSheet
} from 'react-native';

import {
    RootSiblingPortal
} from 'react-native-root-siblings';

const {
    width,
    height
} = Dimensions.get(`screen`);

interface State {
    curShow:boolean,
    maskShow:boolean,
    contentShow:boolean
}

export type Direction = 'top' | 'bottom' | 'left' | 'right' | 'center' | 'none';

interface Props {
    fixed:boolean,
    show:boolean,
    onClose:Function,
    style?:ViewStyle,
    onClosed:Function,
    maskOpacity:number,
    id?:number|string,
    portal:boolean,
    direction:Direction,
    backClose:boolean,
    enableBack:boolean
}

import Mask from './mask';

import Container from './container';

class Modal extends PureComponent<Props,State> {
    constructor(props:Props) {
        super(props);
        const {
            show
        } = props;

        this.state = {
            curShow:show,
            maskShow:show,
            contentShow:show
        }
    }

    static defaultProps = {
        show:false,
        fixed:true,
        portal:true,
        backClose:true,
        maskOpacity:.3,
        direction:'center',
        onClose:() => null,
        onClosed:() => null,
        enableBack:true
    }

    _onPress = () => {
        this.props.onClose();
    }

    componentDidUpdate() {
        const {
            show
        } = this.props;

        const {
            curShow
        } = this.state;

        if(show !== curShow) {
            this.onLaunch(show);
        }
    }

    onLaunch = (show:boolean) => {
        //显示
        if(show) {
            this.onShown()
        }
        else {
            this.onClose();
        }
    }

    onShown = () => {
        this.setState({
            curShow:true,
            maskShow:true,
            contentShow:true
        })
    }

    onClose = () => {
        this.setState({
            maskShow:false,
            contentShow:false
        })
    }

    onContentClosed = () => {
        this.setState({
            maskShow:false
        })
    }

    onMaskClose = () => {
        const {
            id,
            onClosed
        } = this.props;

        this.setState({
            curShow:false
        },() => onClosed(id))
    }

    onBackPress = () => {
        const {
            enableBack,
            backClose
        } = this.props;

        if(!enableBack) {
            return false
        }

        if(backClose) {
            this._onPress();
        }

        return true;
    }

    get containerStyle() {
        const {
            fixed
        } = this.props;

        const _styles = (
            [styles.container]
        )

        _styles.push(
            fixed?styles.fixedStyle:
                styles.coverStyle
        )

        return _styles;
    }

    render() {
        const {
            curShow,
            maskShow,
            contentShow
        } = this.state;

        const {
            style,
            portal,
            children,
            direction,
            maskOpacity
        } = this.props;

        const Portal = (
            portal ? RootSiblingPortal:Fragment
        )

        return (
            <Portal>
                {curShow ? (
                    <View
                        collapsable={false}
                        pointerEvents='box-none'
                        style={[this.containerStyle,style]}
                    >
                        <Mask
                            show={maskShow}
                            maskOpacity={maskOpacity}
                            onClosed={this.onMaskClose}
                        />
                        <Container
                            show={contentShow}
                            children={children}
                            direction={direction}
                            onPressMask={this._onPress}
                            onBackPress={this.onBackPress}
                            onClosed={this.onContentClosed}
                        />
                    </View>
                ):null}
            </Portal>
        )
    }
}

export default Modal;

const styles:any = StyleSheet.create({
    container:{
        zIndex:999,
        position:`absolute`
    },
    coverStyle:{
        left:0,
        right:0,
        top:0,
        bottom:0
    },
    fixedStyle:{
        top:0,
        left:0,
        width,
        height,
    },
    maskStyle:{
        left:0,
        right:0,
        top:0,
        bottom:0,
        position:`absolute`
    }
})

